package com.tarzan.security.evaluator;

import com.tarzan.security.model.LoginUser;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.List;

/**
 * @Package com.tarzan.security.evaluator
 * @Title CustomizePermissionEvaluator
 * @Description TODO 自定义hasPermission权限注解验证
 * @Author liujinshan
 * @CreateTime 2021/7/29 15:28
 */
@Component
public class CustomizePermissionEvaluator implements PermissionEvaluator {
    /**
     * hasPermission鉴权方法
     *    这里仅仅判断PreAuthorize注解中的permission
     *    实际中可以根据业务需求设计数据库通过targetUrl和permission做更复杂鉴权
     * @param authentication     represents the user in question. Should not be null.
     * @param targetDomainObject the domain object for which permissions should be
     *                           checked. May be null in which case implementations should return false, as the null
     *                           condition can be checked explicitly in the expression.
     * @param permission         a representation of the permission object as supplied by the
     *                           expression system. Not null.
     * @return true if the permission is granted, false otherwise
     */
    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        // 获取用户信息
        LoginUser user = (LoginUser) authentication.getPrincipal();
        // 获取用户对应角色的权限(因为SQL中已经GROUP BY了，所以返回的list是不重复的)
        List<String> permissions = user.getPermissions();
        // 权限对比
        return permissions.contains(permission.toString());
    }

    /**
     * Alternative method for evaluating a permission where only the identifier of the
     * target object is available, rather than the target instance itself.
     *
     * @param authentication represents the user in question. Should not be null.
     * @param targetId       the identifier for the object instance (usually a Long)
     * @param targetType     a String representing the target's type (usually a Java
     *                       classname). Not null.
     * @param permission     a representation of the permission object as supplied by the
     *                       expression system. Not null.
     * @return true if the permission is granted, false otherwise
     */
    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        return false;
    }
}
